package nape.phys;
import zpp_nape.Config;
import zpp_nape.Const;
import zpp_nape.util.Flags;
import DummyNapeMain;
import zpp_nape.util.Math;
import zpp_nape.util.Names;
import zpp_nape.util.Pool;
import zpp_nape.util.Lists;
import zpp_nape.shape.Circle;
import zpp_nape.shape.Edge;
import zpp_nape.space.Space;
import zpp_nape.shape.Polygon;
import zpp_nape.shape.Shape;
import zpp_nape.phys.FeatureMix;
import zpp_nape.phys.FluidProperties;
import zpp_nape.phys.Material;
import zpp_nape.phys.Body;
import zpp_nape.geom.AABB;
import zpp_nape.geom.Distance;
import zpp_nape.geom.Mat23;
import zpp_nape.geom.Vec2;
import zpp_nape.geom.VecMath;
import zpp_nape.geom.Collide;
import zpp_nape.dynamics.Arbiter;
import zpp_nape.dynamics.Contact;
import zpp_nape.dynamics.InteractionFilter;
import zpp_nape.constraint.Constraint;
import zpp_nape.dynamics.SpaceArbiterList;
import zpp_nape.constraint.Matrices;
import zpp_nape.constraint.PivotJoint;
import zpp_nape.constraint.WeldJoint;
import nape.util.Flags;
import nape.util.Lists;
import nape.util.Debug;
import nape.space.Space;
import nape.shape.Circle;
import nape.shape.Polygon;
import nape.shape.Edge;
import nape.shape.Shape;
import nape.phys.Material;
import nape.phys.Body;
import nape.geom.AABB;
import nape.geom.Geom;
import nape.geom.Mat23;
import nape.geom.Vec2;
import nape.dynamics.Contact;
import nape.dynamics.Arbiter;
import nape.dynamics.InteractionFilter;
#if swc@:keep#end class FluidProperties{
    public var zpp_inner:ZPP_FluidProperties;
    public var shared(flibget_shared,flibset_shared):Bool;
    inline function flibget_shared()return zpp_inner.shared inline function flibset_shared(shared:Bool){
        if(this.shared!=shared){
            if(this.shared&&!zpp_inner.shapes.empty()){
                while(zpp_inner.shapes.begin().next!=null){
                    var s=zpp_inner.shapes.pop_unsafe();
                    s.fluidProperties=zpp_inner.copy();
                    s.fluidProperties.shapes.add(s);
                }
            }
            zpp_inner.shared=shared;
        }
        return this.shared;
    }
    public var shapes(flibget_shapes,never):ShapeList;
    inline function flibget_shapes(){
        if(zpp_inner.wrap_shapes==null)zpp_inner.wrap_shapes=ZPP_ShapeList.get(zpp_inner.shapes,true);
        return zpp_inner.wrap_shapes;
    }
    public function new(?density:Float=1,?viscosity:Float=1){
        zpp_inner={
            if(ZPP_FluidProperties.zpp_pool==null)new ZPP_FluidProperties();
            else{
                var ret=ZPP_FluidProperties.zpp_pool;
                ZPP_FluidProperties.zpp_pool=ret.next;
                ret;
            }
        };
        zpp_inner.outer=this;
        this.density=density;
        this.viscosity=viscosity;
    }
    #if swc@:keep#end public inline function copy(){
        return new FluidProperties(density,viscosity);
    }
    public var density(flibget_density,flibset_density):Float;
    inline function flibget_density()return("density"=="density"?1000:1)*zpp_inner.density inline function flibset_density(density:Float){
        if(density!=this.density){
            if(({
                #if flash9 var ret:Bool=untyped __global__["isNaN"](density);
                ret;
                #else Math.isNaN(density);
                #end
            }))throw "Error: FluidProperties::"+"density"+" cannot be NaN";
            if(density<0)throw "Error: FluidProperties::"+"density"+" ("+density+") must be >= 0";
            if("density"=="density")zpp_inner.density=density*0.001;
            else zpp_inner.density=density;
            zpp_inner.invalidate();
        }
        return this.density;
    }
    public var viscosity(flibget_viscosity,flibset_viscosity):Float;
    inline function flibget_viscosity()return("viscosity"=="density"?1000:1)*zpp_inner.viscosity inline function flibset_viscosity(viscosity:Float){
        if(viscosity!=this.viscosity){
            if(({
                #if flash9 var ret:Bool=untyped __global__["isNaN"](viscosity);
                ret;
                #else Math.isNaN(viscosity);
                #end
            }))throw "Error: FluidProperties::"+"viscosity"+" cannot be NaN";
            if(viscosity<0)throw "Error: FluidProperties::"+"viscosity"+" ("+viscosity+") must be >= 0";
            if("viscosity"=="density")zpp_inner.viscosity=viscosity*0.001;
            else zpp_inner.viscosity=viscosity;
            zpp_inner.invalidate();
        }
        return this.viscosity;
    }
    @:keep public inline function toString(){
        return "{ density: "+density+" viscosity: "+viscosity+" }";
    }
}
